home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_497 / nlcalc / source / csetup.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  210 lines

  1. /*
  2.  *  CALC      Provides a calculator that opens on the active screen when
  3.  *            you press a specific key sequence.  Otherwise, the program
  4.  *            waits quitely in the background.
  5.  *
  6.  *              Copyright 1989 by Davide P. Cervone.
  7.  *  You may use this code, provided this copywrite notice is kept intact.
  8.  */
  9.  
  10. #define INTUITION_PREFERENCES_H         /* don't need 'em */
  11. #include <intuition/intuitionbase.h>
  12. #include <exec/interrupts.h>
  13. #include <devices/input.h>
  14. #include <libraries/dos.h>
  15. #include <libraries/dosextens.h>
  16. #include <proto/exec.h>
  17.  
  18. #include "cHandler.h"
  19. #include "cSetup.h"
  20.  
  21. extern struct Process *FindTask();
  22.  
  23.  
  24. #define GETSTARTUP(p)       ((struct StartupMessage *)GetMsg(p))
  25.  
  26. #define ONE     1L
  27. #define SIGBREAKF_ANY\
  28.    (SIGBREAKF_CTRL_C| SIGBREAKF_CTRL_D| SIGBREAKF_CTRL_E| SIGBREAKF_CTRL_F)
  29.  
  30.  
  31. extern void myHandlerStub();
  32. #ifndef SWINDOWS
  33. extern void aCloseScreen();
  34. extern void cCloseScreen();
  35. long OldCloseScreen;
  36. #endif
  37.  
  38.  
  39. LONG CalcSMask;                 /* Signal for calc to open on active screen */
  40. static LONG CalcSSignal;        /* Signal number for CalcSMask */
  41.  
  42. #ifndef SWINDOWS
  43. LONG CalcCMask;                 /* Signal for screen close */
  44. static LONG CalcCSignal;        /* Signal number for CalcCMask */
  45. #endif
  46.  
  47.  
  48. struct Task *CalcTask;          /* Pointer to Calc task */
  49. static struct Task *ParentTask; /* Pointer to parent task */
  50.  
  51.  
  52. extern UWORD KeyCode;           /* KeyCode to activate Calc */
  53. extern UWORD Qualifiers;        /*   and required qualifiers */
  54.  
  55.  
  56. static struct Interrupt Calc_Interrupt = /* the Interrupt needed to add a */
  57. {                                         /*  handler to the input chain */
  58.    {NULL, NULL, 0, 51, NULL},             /*  ln_Pri = 51 (before Intuition) */
  59.    NULL,
  60.    &myHandlerStub                         /* the handler to add */
  61. };
  62.  
  63. static struct HandlerData cHandlerData =
  64. {
  65.    {                                            /* the MsgPort is pre-setup */
  66.       {NULL,NULL, NT_MSGPORT, 0, PORTNAME},     /*  to include the name and */
  67.       PA_IGNORE, 0, NULL,                       /*  type so that it can just */
  68.       {NULL,NULL,NULL, 0,0}                     /*  be added to the port list */
  69.    },                                           /*  so it can be found later */
  70.    MAJVERS,MINVERS, MINLOADVER,         /* the handler versio numbers */
  71.    NULL,                                /* the handler code segment */
  72.    &IntuitionBase,                      /* pointer to IntuitionBase and */
  73.    &GfxBase,                            /*   GfxBase (set up by loader) */
  74.    
  75.    &Calc_Interrupt,                     /* the interrupt used by Input.Device */
  76.    &ParentTask,                         /* so we know who to signal later */
  77.  
  78.    &KeyCode,                            /* the KeyCode to acticate calc */
  79.    &Qualifiers,                         /*   and required qualifiers */
  80.  
  81. #ifndef SWINDOWS   
  82.    &aCloseScreen,                       /* ASM CloseScreen stub */
  83.    &OldCloseScreen,                     /* result of SetFunction */
  84. #else
  85.    NULL,NULL
  86. #endif
  87. };
  88.  
  89.  
  90. /*
  91.  *  cExit()
  92.  *
  93.  *  End CalcTask from running.  Forbid() so that we are not unloaded until
  94.  *  after we're done exiting.  Signal the parent that we are done running,
  95.  *  and exit.
  96.  */
  97.  
  98. void cExit()
  99. {
  100.    Forbid();
  101.    if (ParentTask) Signal(ParentTask,ENDSIGNAL);
  102.    Exit(0);
  103. }
  104.  
  105.  
  106. /*
  107.  *  GetSignal()
  108.  *
  109.  *  Allocate a signal (error if none available) and set the mask to
  110.  *  the proper value.
  111.  */
  112.  
  113. #define DEFAULTSIGNAL       20
  114.  
  115. void GetSignal(theSignal,theMask)
  116. LONG *theSignal, *theMask;
  117. {
  118.    LONG signal;
  119.  
  120.    if ((signal = AllocSignal(-ONE)) == -ONE) signal = DEFAULTSIGNAL;
  121.    *theSignal = signal;
  122.    *theMask = (ONE << signal);
  123. }
  124.  
  125.  
  126. /*
  127.  *  WaitForStartup()
  128.  *
  129.  *  Find our task pointer and wait for a startup message passed buy the loader.
  130.  *  (This structure is non-standard and is defined in cSetup.h).  Check that
  131.  *  we have not been signaled to end (in case the user executed the handler
  132.  *  as a command, for example).  Otherwise, once we have received the
  133.  *  startup message, get the parent task pointer from the message, and
  134.  *  check the loader version number.  If OK, then set the HandlerData so
  135.  *  the loader can do its thing.  Finally, reply to the message to inform 
  136.  *  the loader that everything is ready for it.
  137.  */
  138.  
  139. static void WaitForStartup()
  140. {
  141.    struct Process *cTask = FindTask(NULL);
  142.    struct MsgPort *cPort = &cTask->pr_MsgPort;
  143.    struct StartupMessage *sMessage = NULL;
  144.    ULONG Mask = (ONE << cPort->mp_SigBit);
  145.    ULONG signals;
  146.    
  147.    CalcTask = (struct Task *)cTask;
  148.    while (sMessage == NULL)
  149.    {
  150.       signals = Wait(Mask|ENDSIGNAL);
  151.       if (signals & ENDSIGNAL) cExit();
  152.       sMessage = GETSTARTUP(cPort);
  153.    }
  154.    ParentTask = sMessage->sm_ParentTask;
  155.    if (sMessage->sm_LoadVers < MINLOADVER)
  156.       sMessage->sm_HandlerData = NULL;
  157.      else
  158.       sMessage->sm_HandlerData = &cHandlerData;
  159.    ReplyMsg(sMessage);
  160. }
  161.  
  162.  
  163. /*
  164.  *  InitCalc()
  165.  *
  166.  *  Clear any pending signals, and wait for the startup message from the
  167.  *  loader.  Then wait for the loader to signal us that it is finished
  168.  *  setting things up for us.  If it signaled an END, then exit, otherwise
  169.  *  allocate the signals that we will need
  170.  */
  171.  
  172. void InitCalc()
  173. {
  174.    ULONG signals;
  175.  
  176.    SetSignal(0L,SIGBREAKF_ANY);
  177.    WaitForStartup();
  178.    signals = Wait(STARTSIGNAL | ENDSIGNAL);
  179.    if (signals & ENDSIGNAL) cExit();
  180.    GetSignal(&CalcSSignal,&CalcSMask);
  181. #ifndef SWINDOWS
  182.    GetSignal(&CalcCSignal,&CalcCMask);
  183. #endif
  184. }
  185.  
  186.  
  187. /*
  188.  *  ConfirmExit()
  189.  *
  190.  *  Called when the loader tries to unload the handler.  First we signal
  191.  *  the loader that everything is ready for it to try to deinstall us.  
  192.  *  Then we wait for it to signal that everything has be removed properly.
  193.  *  If it signals us with ENDSIGNAL we can safely end (it has been able to 
  194.  *  remove everything).  Otherwise, we must continue to run.
  195.  */
  196.  
  197. int ConfirmExit()
  198. {
  199.    ULONG signals;
  200.    int NotDone = TRUE;
  201.  
  202.    if (ParentTask)
  203.    {
  204.       Signal(ParentTask,ENDSIGNAL);
  205.       signals = Wait(ENDSIGNAL | STARTSIGNAL);
  206.       if (signals & ENDSIGNAL) NotDone = FALSE;
  207.    }
  208.    return(NotDone);
  209. }
  210.